package com.leo.train.business.service.Impl;

import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leo.train.business.dto.SeatQueryDto;
import com.leo.train.business.entity.Carriage;
import com.leo.train.business.entity.Seat;
import com.leo.train.business.mapper.CarriageMapper;
import com.leo.train.business.mapper.SeatMapper;
import com.leo.train.business.service.SeatService;
import com.leo.train.business.vo.SeatVo;
import com.leo.train.common.enums.SeatColEnum;
import com.leo.train.common.enums.SeatTypeEnum;
import com.leo.train.common.exception.BusinessException;
import com.leo.train.common.exception.BusinessExceptionEnum;
import com.leo.train.common.resp.PageResult;
import com.leo.train.common.util.SnowUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SeatServiceImpl implements SeatService {
    @Autowired
    private SeatMapper seatMapper;
    @Autowired
    private CarriageMapper carriageMapper;
    @Override
    public void save(Seat seat) {
        Long id = seat.getId();
        if (id == null) {
            // 新增
            seat.setId(SnowUtil.getSnowflakeNextId());
            seat.setCreateTime(new Date());
            seat.setUpdateTime(new Date());
            seatMapper.insert(seat);
        } else {
            // 修改
            seat.setUpdateTime(new Date());
            seatMapper.update(seat);
        }
    }

    @Override
    public void deleteById(Long id) {
        seatMapper.deleteById(id);
    }

    @Override
    public PageResult<SeatVo> list(SeatQueryDto seatQueryDto) {
        PageHelper.startPage(seatQueryDto.getPage(), seatQueryDto.getPageSize());
        Page<Seat> page = seatMapper.list(seatQueryDto);
        List<SeatVo> seatVoList = page.getResult().stream().map(seat -> {
            SeatVo seatVo = new SeatVo();
            BeanUtils.copyProperties(seat, seatVo);
            seatVo.setSeatTypeName(SeatTypeEnum.getEnumByCode(seat.getSeatType()).getDesc());
            seatVo.setColType(SeatColEnum.getEnumByCode(seat.getCol()).getDesc());
            return seatVo;
        }).collect(Collectors.toList());
        return new PageResult<>(page.getTotal(), seatVoList);
    }

    @Override
    public SeatVo detail(Long id) {
        Seat seat = seatMapper.selectById(id);
        if (seat == null) {
            throw new BusinessException(BusinessExceptionEnum.BUSINESS_SEAT_NOT_EXIST);
        }
        SeatVo seatVo = new SeatVo();
        BeanUtils.copyProperties(seat, seatVo);
        seatVo.setSeatTypeName(SeatTypeEnum.getEnumByCode(seat.getSeatType()).getDesc());
        seatVo.setColType(SeatColEnum.getEnumByCode(seat.getCol()).getDesc());
        return seatVo;
    }

    @Override
    @Transactional // 开启事务注解
    public void generateSeats(String trainCode) {
        Date now = new Date();
        // 1. 先删除trainCode关联的所有座位信息
        seatMapper.deleteByTrainCode(trainCode);
        // 2. 根据trainCode查询对应的所有车厢
        List<Carriage> carriageList = carriageMapper.listByTrainCode(trainCode);
        log.info("查询到车厢：{}", carriageList);
        // 3.遍历车厢
        carriageList.forEach(carriage -> {
            // 3.1 拿到车厢数据：行数、座位类型(得到列数)
            int rowCount = carriage.getRowCount();
            String seatType = carriage.getSeatType();
            int seatIndex = 1; // 座位索引
            /*
                3.2 根据座位类型获取出所有的列
                比如车厢类型是一等座，则筛选出columnList=[A,C,D,F]
                比如车厢类型是二等座，则筛选出columnList=[A,B,C,D,F]
             */
            List<SeatColEnum> columnList = SeatColEnum.getColsByType(seatType);
            // 3.3 循环行数
            for (int row = 1; row <= rowCount; row++) {
                // 3.4 循环列数
                for(SeatColEnum col : columnList) {
                    // 3.5 生成座位
                    Seat seat = new Seat();
                    seat.setId(SnowUtil.getSnowflakeNextId());
                    seat.setTrainCode(trainCode);
                    seat.setCarriageIndex(carriage.getIndex());
                    // 如果是1位则补0，如1行A列则变为01行A列
                    seat.setRow(StrUtil.fillBefore(String.valueOf(row), '0', 2));
                    seat.setCol(col.getCode());
                    seat.setSeatType(seatType);
                    seat.setCarriageSeatIndex(seatIndex++); // 每个车厢的座位对应的索引
                    seat.setCreateTime(now);
                    seat.setUpdateTime(now);
                    seatMapper.insert(seat);
                }
            }
        });
    }
}
